package resolvers

import (
	"context"
	"happy-sudoku/graphql/models"
	"happy-sudoku/internal/model"
	"happy-sudoku/internal/service"
	"happy-sudoku/internal/sudoku"
)

type mutationRootResolver struct{ *RootResolver }

func (r *mutationRootResolver) Login(ctx context.Context, playerToken string) (*models.AuthPayload, error) {
	player, err := r.playerSrv.Login(ctx, playerToken)
	if err != nil {
		return nil, err
	}
	// generate cookie
	// !! TODO: find a way to handle cookie
	auth := model.MakeAuth()
	auth.PlayerID = player.ID
	tokenStr, err := r.authSrv.GenerateToken(auth)
	if err != nil {
		return nil, err
	}
	authPayload := &models.AuthPayload{
		Token:  tokenStr,
		Player: player,
	}
	return authPayload, nil
}

func (r *mutationRootResolver) Logout(ctx context.Context) (bool, error) {
	auth := model.ForAuthContext(ctx)
	return true, r.playerSrv.Logout(ctx, auth.PlayerID)
}

func (r *mutationRootResolver) Register(ctx context.Context, input model.RegisterInput) (*models.RegisterPayload, error) {
	player, err := r.playerSrv.Register(ctx, input)
	if err != nil {
		return nil, err
	}
	auth := model.MakeAuth()
	auth.PlayerID = player.ID
	tokenStr, err := r.authSrv.GenerateToken(auth)
	if err != nil {
		return nil, err
	}
	authPayload := &models.RegisterPayload{
		Token:      tokenStr,
		Player:     player,
		LoginToken: player.Token,
	}
	// add auth to context
	return authPayload, nil
}

func (r *mutationRootResolver) CreateRoom(ctx context.Context) (*model.Room, error) {
	auth := model.ForAuthContext(ctx)
	return r.roomSrv.CreateRoom(ctx, auth.PlayerID)
}

func (r *mutationRootResolver) SetRoomSetting(ctx context.Context, roomID int, setting models.RoomSettingInput) (*model.Room, error) {
	auth := model.ForAuthContext(ctx)
	updateSettingInput := service.UpdateSettingInput{
		RoomID:   roomID,
		PlayerID: auth.PlayerID,
		RoomSetting: model.RoomSetting{
			Mode:       setting.Mode,
			MaxPlayer:  setting.MaxPlayer,
			Duration:   setting.Duration,
			Difficulty: setting.Difficulty,
		},
	}
	return r.roomSrv.UpdateSetting(ctx, updateSettingInput)
}

func (r *mutationRootResolver) JoinRoom(ctx context.Context, roomID int) (*model.Room, error) {
	auth := model.ForAuthContext(ctx)
	return r.roomSrv.JoinRoom(ctx, roomID, auth.PlayerID)
}

func (r *mutationRootResolver) LeaveRoom(ctx context.Context) (bool, error) {
	auth := model.ForAuthContext(ctx)
	err := r.roomSrv.LeaveRoom(ctx, auth.PlayerID)
	return false, err
}

func (r *mutationRootResolver) StartGame(ctx context.Context) (bool, error) {
	auth := model.ForAuthContext(ctx)
	err := r.roomSrv.StartGame(ctx, auth.PlayerID)
	return false, err
}

func (r *mutationRootResolver) PushAnswer(ctx context.Context, answer sudoku.GridType) (*sudoku.AnswerRes, error) {
	auth := model.ForAuthContext(ctx)
	return r.roomSrv.PushAnswer(ctx, auth.PlayerID, answer)
}

func (r *mutationRootResolver) ToggleReadyOrWait(ctx context.Context, ready bool) (*bool, error) {
	auth := model.ForAuthContext(ctx)
	val, err := r.roomSrv.TogglePlayerReadyOrWait(ctx, auth.PlayerID, ready)
	return &val, err
}
